<?php

/**
 * Created by PhpStorm.
 * User: 小灰灰
 * Date: 2023-02-02
 * Time: 14:13:24
 * Info:
 */
session_start();
defined('IN_YZMPHP') or exit('Access Denied');

class uploads
{

    private $isadmin;

    private $groupid;

    private $userid;

    private $username;

    public function __construct()
    {
        $_adminId      = get_session('admin_id');
        $_userId       = get_session('_userid');
        $this->user_id = isset($_adminId) ? $_adminId : (isset($_userId) ? $_userId : 0);
        if ( ! $this->user_id) {
            showmsg("请先登录", U('admin/index/login'), 1);
        }
        $this->role_id = get_session('role_id') ? get_session('role_id') : 0;
    }

    /**
     * 上传文件
     */
    public function upload($isBase64 = false)
    {
        $filename            = 'file';
        $open_watermark      = (int)get_config('watermark_enable') ? (int)get_config('watermark_enable') : 0;
        $filetype            = ! empty(input('get.action')) ? input('get.action') : 'image';
        $group_id            = ! empty(input('post.group_id')) ? intval(input('post.group_id')) : 0;
        $editor_type         = ! empty(input('get.editor_type')) ? input('get.editor_type') : 'ueditor';
        $option              = array();
        $option['allowtype'] = $this->_get_upload_types($filetype);

        if ($isBase64 === true) {
            //涂鸦上传（base64）
            return $this->upBase64(input('post.file'));
        }

        $upload_type = C('upload_type', 'host');
        yzm_base::load_model($upload_type, '', 0);

        if ( ! class_exists($upload_type)) {
            return_error("附件上传类「".$upload_type."」不存在！");
        }

        $upload = new $upload_type($option);
        if ($upload->uploadfile($filename)) {
            $fileinfo               = $upload->getnewfileinfo();
            $fileinfo['originname'] = safe_replace($fileinfo['originname']);
            $fileinfo['group_id']   = $group_id;

            $imgUlr = $fileinfo['filepath'].$fileinfo['filename'];
            //加水印
            if ($open_watermark) {
                watermark($imgUlr);
            }
            //写入数据库
            $this->_att_write($fileinfo);
            if ($editor_type == 'ueditor') {
                return_json(['state' => 'SUCCESS', 'url' => $imgUlr]);
            } elseif ($editor_type == 'sdEditor') {
                return_json(['state' => 'success', 'msg' => $imgUlr, 'name' => $fileinfo['filename']]);
            } else {
                return_json(["code" => 200, 'url' => $imgUlr, 'msg' => '上传成功']);
            }
        } else {
            if ($editor_type == 'ueditor') {
                return_json(['state' => $upload->geterrormsg()]);
            } else {
                return_error($upload->geterrormsg());
            }
        }
    }

    /**
     * 获取上传类型
     */
    private function _get_upload_types($type)
    {
        $arr   = explode(',', ($type == 'image' ? get_config('upload_types_image') : get_config('upload_types_file')));
        $allow = array(
            'png',
            'gif',
            'jpg',
            'jpeg',
            'webp',
            'bmp',
            'ico',
            'zip',
            'rar',
            '7z',
            'gz',
            'doc',
            'docx',
            'xls',
            'xlsx',
            'ppt',
            'pptx',
            'pdf',
            'txt',
            'csv',
            'mp3',
            'mp4',
            'avi',
            'wmv',
            'rmvb',
            'flv',
            'wma',
            'wav',
            'amr',
            'ogg',
            'ogv',
            'webm',
            'swf',
            'mkv',
            'torrent'
        );
        foreach ($arr as $key => $val) {
            if ( ! in_array($val, $allow)) {
                unset($arr[$key]);
            }
        }

        return $arr;
    }

    /**
     * 上传附件写入数据库
     */
    private function _att_write($fileinfo)
    {
        $param = [
            'storage'     => "local",
            'group_id'    => $fileinfo['group_id'],
            'file_url'    => $fileinfo['filepath'].$fileinfo['filename'],
            'file_name'   => $fileinfo['filename'],
            'file_size'   => $fileinfo['filesize'],
            'file_type'   => "",
            'extension'   => $fileinfo['filetype'],
            'is_image'    => is_img($fileinfo['filetype']) ? 1 : 0,
            'upload_ip'   => getip(),
            'user_id'     => $this->user_id,
            'role_id'     => $this->role_id,
            'create_time' => time()
        ];
        D('upload_file')->insert($param);
    }

    /**
     * editor上传服务配置项输出
     * @return array
     */
    public function public_ueditor_config()
    {

        $config = $this->config_ueditor();
        $action = input('get.action');
        switch ($action) {
            //图片上传
            case 'image':
                return $this->upload();

            // 图片列表
            case 'listImage':
                $start = (int)input('get.start', 0);
                $size  = (int)input('get.size', 20);

                return $this->action_list($config, 'listImage', $start, $size);
            // 上传视频
            case 'video':
                $result = ['state' => 'ERROR', 'url' => ''];

                return $this->output($result);

            //文件上传
            case 'file':
                return $this->upload();

            //文件列表
            case 'listFile':
                $start = (int)input('get.start', 0);
                $size  = (int)input('get.size', 20);

                return $this->action_list($config, 'listFile', $start, $size);

            // 涂鸦上传
            case 'crawl':
                return $this->upload(true);
            default:
                return $this->output($config);
        }
    }

    private function config_ueditor()
    {
        $stroage_local_dir = 'local';

        $imageAllowFiles = get_config('upload_types_image');
        $imageAllowFiles = explode(',', $imageAllowFiles);
        foreach ($imageAllowFiles as $key => $v) {
            $imageAllowFiles[$key] = ".".$v;
        }
        $fileAllowFiles = get_config('upload_types_file');
        $fileAllowFiles = explode(',', $fileAllowFiles);
        foreach ($fileAllowFiles as $key => $v) {
            $fileAllowFiles[$key] = ".".$v;
        }

        $config = [
            // 上传图片配置项
            "imageActionName"         => "image",
            "imageFieldName"          => "file",
            "imageMaxSize"            => 1024 * 1024 * 10,
            "imageAllowFiles"         => $imageAllowFiles,
            "imageCompressEnable"     => true,
            "imageCompressBorder"     => 5000,
            "imageInsertAlign"        => "none",
            "imageUrlPrefix"          => "",

            // 涂鸦图片上传配置项
            "scrawlActionName"        => "crawl",
            "scrawlFieldName"         => "file",
            "scrawlMaxSize"           => 1024 * 1024 * 10,
            "scrawlUrlPrefix"         => "",
            "scrawlInsertAlign"       => "none",

            // 截图工具上传
            "snapscreenActionName"    => "snap",
            "snapscreenUrlPrefix"     => "",
            "snapscreenInsertAlign"   => "none",

            // 抓取
            "catcherLocalDomain"      => ["127.0.0.1", "localhost"],
            "catcherActionName"       => "catch",
            "catcherFieldName"        => "source",
            "catcherUrlPrefix"        => "",
            "catcherMaxSize"          => 1024 * 1024 * 10,
            "catcherAllowFiles"       => $imageAllowFiles,

            // 上传视频配置
            "videoActionName"         => "video",
            "videoFieldName"          => "file",
            "videoUrlPrefix"          => "",
            "videoMaxSize"            => 1024 * 1024 * 100,
            "videoAllowFiles"         => ['.mp4'],

            // 上传文件配置
            "fileActionName"          => "file",
            "fileFieldName"           => "file",
            "fileUrlPrefix"           => "",
            "fileMaxSize"             => 1024 * 1024 * 100,
            "fileAllowFiles"          => $fileAllowFiles,

            // 列出图片
            "imageManagerActionName"  => "listImage",   /* 执行图片管理的action名称 */
            "imageManagerListPath"    => "./uploads/",    /* 指定要列出图片的目录 */
            "imageManagerListSize"    => 20,    /* 每次列出文件数量 */
            "imageManagerUrlPrefix"   => "",    /* 图片访问路径前缀 */
            "imageManagerInsertAlign" => "none",    /* 插入的图片浮动方式 */
            "imageManagerAllowFiles"  => $imageAllowFiles, /* 列出的文件类型 */

            // 列出指定目录下的文件
            "fileManagerActionName"   => "listFile",
            "fileManagerListPath"     => "./uploads/",
            "fileManagerUrlPrefix"    => "",
            "fileManagerListSize"     => 20,
            "fileManagerAllowFiles"   => $fileAllowFiles

        ];

        return $config;
    }

    /**
     * 百度编辑输出
     */
    private function output($data)
    {
        return_json($data);
    }

    /**
     * 百度编辑器列出文件
     */
    private function action_list($config, $type = 'listImage', $start = 0, $size = 20)
    {
        switch ($type) {
            case 'listImage':
                $allowFiles = $config['imageManagerAllowFiles'];
                $path       = $config['imageManagerListPath'];
                break;
            case "listFile":
                $allowFiles = $config['fileManagerAllowFiles'];
                $path       = $config['fileManagerListPath'];
                break;
        }
        $allowFiles = substr(str_replace(".", "|", join("", $allowFiles)), 1);
        /* 获取参数 */
        $end = $start + $size;
        /* 获取文件列表 */
        $files = $this->getfiles($path, $allowFiles);

        if ( ! empty($files) && count($files) <= 0) {
            return_json(array(
                "state" => "no match file",
                "list"  => array(),
                "start" => $start,
                "total" => count($files)
            ));
        }
        /* 获取指定范围的列表 */
        $len = count($files);
        for ($i = min($end, $len) - 1, $list = []; $i < $len && $i >= 0 && $i >= $start; $i--) {
            $list[] = $files[$i];
        }
        $list = arrayOrder($list, 'mtime');

        /* 返回数据 */
        $result = array(
            "state" => "SUCCESS",
            "list"  => $list,
            "start" => $start,
            "total" => count($files)
        );

        return_json($result);

    }

    /**
     * 处理base64编码的图片上传
     * @return mixed
     */
    private function upBase64($fileField)
    {
        $base64_image_content = $fileField;
        if (empty($base64_image_content)) {
            return false;
        }
        //合成图片的base64编码成
        $base64_image_content = "data:image/png;base64,{$base64_image_content}";
        //匹配出图片的信息
        $match = preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result);
        if ( ! $match) {
            return false;
        }

        //解码图片内容
        $base64_image = str_replace($result[1], '', $base64_image_content);
        $file_content = base64_decode($base64_image);
        $file_type    = $result[2];

        //如果没指定目录,则保存在当前目录下
        $pathTime = date('Ymd');
        $filePath = "/uploads/crawl/".$pathTime."/";
        $path     = YZMPHP_PATH.$filePath;
        if ( ! is_dir($path)) {
            @mkdir($path, 0777, true);
        }
        $file_name = time().".{$file_type}";

        $new_file = $path.$file_name;
        if (file_exists($new_file)) {
            //有同名文件删除
            @unlink($new_file);
        }
        if (file_put_contents($new_file, $file_content)) {
            return_json(['state' => 'SUCCESS', 'url' => $filePath.$file_name]);
        }

        return false;
    }

    /**
     * 遍历获取目录下的指定类型的文件
     *
     * @param       $path
     * @param array $files
     *
     * @return array
     */
    /**
     * 遍历获取目录下的指定类型的文件
     *
     * @param       $path
     * @param array $files
     *
     * @return array
     */
    function getfiles($path, $allowFiles, &$files = array())
    {
        if ( ! is_dir($path)) {
            return null;
        }
        if (substr($path, strlen($path) - 1) != '/') {
            $path .= '/';
        }
        $handle = opendir($path);
        while (false !== ($file = readdir($handle))) {
            if ($file != '.' && $file != '..') {
                $path2 = $path.$file;
                if (is_dir($path2)) {
                    $this->getfiles($path2, $allowFiles, $files);
                } else {
                    if (preg_match("/\.(".$allowFiles.")$/i", $file)) {
                        $files[] = array(
                            't'     => $_SERVER['DOCUMENT_ROOT'],
                            'url'   => str_replace("./", "/", $path2),
                            'mtime' => filemtime($path2)
                        );
                    }
                }
            }
        }
        $files = arrayOrder($files, 'mtime');

        return $files;
    }
}
